#include "MultiMsg_Test.h"

#include "server/multiProtocol/multiMsg.h"
#include "server/multiProtocol/multiRing.h"
#include "server/multiProtocol/multiJoin.h"
#include "server/multiProtocol/multiDiscovery.h"
#include "Poco/Exception.h"
#include "Poco/SAX/SAXException.h"
#include <iostream>
#include <string>
/*********************************************************/
std::string MultiMsgTest::name()
{
	return("MultiMsg");
}
/*********************************************************/
bool MultiMsgTest::runUnitTests()
{
	bool result = true;

	if ( !multiRingParseTest() ) result = false;
	if ( !multiDiscParseTest() ) result = false;
	if ( !multiJoinParseTest() ) result = false;

	return( result ) ;
}
/*********************************************************/
bool MultiMsgTest::multiJoinParseTest()
{
	std::cout << "Running: multiJoinParseTest()";
	std::cout.flush();
	try {
		std::string	msg = "<MGS type='JOIN'><hash>TEST</hash><addr>127.0.0.1:5000</addr><pred>127.0.0.1:5001</pred><succ>127.0.0.1:5003</succ></MGS>";
		MultiMsg* mMsg = MultiMsg::deserialize(msg);

		// Was the message parsed?
		if ( !mMsg ) {
			std::cout << "... failed, parser returned nil when parsing MultiJoin msg!" << std::endl;
			return( false );
		}

		// Did we get a Join packet and nothing else?
		MultiJoin* mJoin = dynamic_cast<MultiJoin*>(mMsg);
		if ( !mJoin ) {
			std::cout << "... failed, incorrect class generated. Expected MultiJoin!" << std::endl;
			return( false );
		}

		// Did the deserialization correctly convert the packet elements?
		if (( mJoin->getHash() != "TEST" ) || ( mJoin->getAddr() != "127.0.0.1:5000") || (mJoin->getPred() != "127.0.0.1:5001") || (mJoin->getSucc() != "127.0.0.1:5003")) {
			std::cout << "... failed! Incorrect values were parsed!" << std::endl;
			return false;
		}
		
	} catch(Poco::InvalidArgumentException& e) {
		std::cout << "... failed with exception: " << e.displayText() << std::endl;
		return( false );
	} catch(std::exception& e) {
		std::cout << "... failed with exception: " << e.what() << std::endl;
		return( false );
	} catch(...) {
		std::cout << "... failed with unknown exception" << std::endl;
		return( false );
	}
	std::cout << "... success!" << std::endl;
	return( true );
}
/*********************************************************/
bool MultiMsgTest::multiDiscParseTest()
{
	std::cout << "Running: multiDiscParseTest()";
	std::cout.flush();
	try {
		std::string	msg = "<MGS type='DISCOVERY'></MGS>";
		MultiMsg* mMsg = MultiMsg::deserialize(msg);

		if ( !mMsg ) {
			std::cout << "... failed, parser returned nil when parsing MultiDiscovery msg!" << std::endl;
			return( false );
		}

		MultiDiscovery* mDisc = dynamic_cast<MultiDiscovery*>(mMsg);
		if ( !mDisc ) {
			std::cout << "... failed, incorrect class generated. Expected MultiDiscovery!" << std::endl;
			return( false );
		}
		
	} catch(Poco::InvalidArgumentException& e) {
		std::cout << "... failed with exception: " << e.displayText() << std::endl;
		return( false );
	} catch(...) {
		std::cout << "... failed with unknown exception" << std::endl;
		return( false );
	}
	std::cout << "... success!" << std::endl;
	return( true );
}
/*********************************************************/
bool MultiMsgTest::multiRingParseTest()
{
	std::cout << "Running: multiRingParseTest()";
	std::cout.flush();
	try {
		std::string	msg = "<MGS type='RING'><hash>TEST</hash><pred>000.000.000.000:0000</pred><succ>000.000.000.000:0000</succ><addr>127.0.0.1:5000</addr></MGS>";
		MultiMsg* mMsg = MultiMsg::deserialize(msg);

		// Was the message parsed?
		if ( !mMsg ) {
			std::cout << "... failed, parser returned nil when parsing MultiRing msg!" << std::endl;
			return( false );
		}

		// Did we get a Ring packet and nothing else?
		MultiRing* mRing = dynamic_cast<MultiRing*>(mMsg);
		if ( !mRing ) {
			std::cout << "... failed, incorrect class generated. Expected MultiRing!" << std::endl;
			return( false );
		}

		// Did the deserialization correctly convert the packet elements?
		if (( mRing->getPredecessorAddr() != "000.000.000.000:0000" ) || ( mRing->getSuccessorAddr() != "000.000.000.000:0000" ) || (mRing->getHash() != "TEST") || (mRing->getAddr() != "127.0.0.1:5000")) {
			std::cout << "... failed! Incorrect values were parsed!" << std::endl;
			return false;
		}
		
	} catch(Poco::InvalidArgumentException& e) {
		std::cout << "... failed with exception: " << e.displayText() << std::endl;
		return( false );
	} catch(std::exception& e) {
		std::cout << "... failed with exception: " << e.what() << std::endl;
		return( false );
	} catch(...) {
		std::cout << "... failed with unknown exception" << std::endl;
		return( false );
	}
	std::cout << "... success!" << std::endl;
	return( true );
}
